package com.example.batch.core.scaling;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.example.batch.core.datasource.DynamicRoutingDataSource;
import com.example.batch.core.loadbalancer.DataSourceLoadBalancer;
import com.example.batch.core.metrics.MetricsCollector;
import com.example.batch.core.datasource.DataSourceProperties;
import javax.sql.DataSource;

@Component
@Slf4j
public class DataSourceScalingManager {
    
    private final DynamicRoutingDataSource dynamicDataSource;
    private final DataSourceLoadBalancer loadBalancer;
    private final MetricsCollector metricsCollector;
    
    @Value("${spring.batch.datasource.scaling.min-instances}")
    private int minInstances;
    
    @Value("${spring.batch.datasource.scaling.max-instances}")
    private int maxInstances;
    
    @Value("${spring.batch.datasource.scaling.scale-up-threshold}")
    private double scaleUpThreshold;
    
    @Value("${spring.batch.datasource.scaling.scale-down-threshold}")
    private double scaleDownThreshold;
    
    @Scheduled(fixedRate = 60000)
    public void autoScale() {
        dataSourceGroups.forEach((groupName, dataSources) -> {
            double avgLoad = calculateGroupLoad(groupName);
            
            if (avgLoad > scaleUpThreshold && dataSources.size() < maxInstances) {
                scaleUp(groupName);
            } else if (avgLoad < scaleDownThreshold && dataSources.size() > minInstances) {
                scaleDown(groupName);
            }
        });
    }
    
    public synchronized void scaleUp(String groupName) {
        try {
            DataSourceProperties template = getTemplateConfig(groupName);
            String newName = generateDataSourceName(groupName);
            
            // 创建新的数据源配置
            DataSourceProperties newConfig = cloneWithNewProperties(template, newName);
            
            // 创建并验证新数据源
            DataSource newDataSource = createAndValidateDataSource(newConfig);
            
            // 添加到路由
            addToRouting(newName, newDataSource);
            
            // 更新负载均衡器
            loadBalancer.addDataSource(groupName, newName, newDataSource);
            
            log.info("Successfully scaled up data source group: {}", groupName);
        } catch (Exception e) {
            log.error("Failed to scale up data source group: " + groupName, e);
        }
    }
} 